<template>
    <div class="ebook-reader">
        <div id="read"></div>
        <div class="ebook-reader-mask"
             @click="onMaskClick"
             @touchmove="move"
             @touchend="moveEnd"
             @mousedown.left="onMouseEnter"
             @mousemove.left="onMouseMove"
             @mouseup.left="onMouseEnd"
        >
        </div>
    </div>
</template>

<script>
  import { ebookMixin } from '../../utils/mixin'
  import Epub from 'epubjs'
  import {
    getFontFamily,
    getFontSize,
    getLocation,
    getTheme,
    saveFontFamily,
    saveFontSize,
    saveTheme
  } from '../../utils/localStorage'
  import { flatten } from '../../utils/book'

  global.ePub = Epub

  export default {
    name: 'EbookReader',
    mixins: [ebookMixin],
    methods: {
      // 1 - 鼠标进入
      // 2 - 鼠标进入后的移动
      // 3 - 鼠标从移动状态松手
      // 4 - 鼠标还原
      // 鼠标松开
      onMouseEnd (e) {
        if (this.mouseState === 2) {
          this.setOffsetY(0)
          this.firstOffsetY = null
          this.mouseState = 3
        } else {
          this.mouseState = 4
        }
        const time = e.timeStamp - this.mouseStartTime
        if (time < 100) {
          this.mouseState = 4
        }
        e.preventDefault()
        e.stopPropagation()
      },
      // 鼠标移动
      onMouseMove (e) {
        if (this.mouseState === 1) {
          this.mouseState = 2
        } else if (this.mouseState === 2) {
          let offsetY = 0
          if (this.firstOffsetY) {
            offsetY = e.clientY - this.firstOffsetY
            this.setOffsetY(offsetY)
          } else {
            this.firstOffsetY = e.clientY
          }
        }
        e.preventDefault()
        e.stopPropagation()
      },
      // 鼠标按下
      onMouseEnter (e) {
        this.mouseState = 1
        // console.log(this.mouseState)
        this.mouseStartTime = e.timeStamp
        e.preventDefault()
        e.stopPropagation()
      },
      // 移动开始
      move (e) {
        let offsetY = 0
        // firstOffsetY 最开始的y轴位置
        if (this.firstOffsetY) {
          offsetY = e.changedTouches[0].clientY - this.firstOffsetY
          this.setOffsetY(offsetY)
        } else {
          this.firstOffsetY = e.changedTouches[0].clientY
        }
        e.preventDefault()
        e.stopPropagation()
      },
      // 移动结束时
      moveEnd (e) {
        this.setOffsetY(0)
        this.firstOffsetY = null
      },
      // 蒙板点击事件
      onMaskClick (e) {
        if (this.mouseState && (this.mouseState === 2 || this.mouseState === 3)) {
          return
        }
        const offsetX = e.offsetX
        const width = window.innerWidth
        if (offsetX > 0 && offsetX < width * 0.3) {
          this.prevPage()
        } else if (offsetX > 0 && offsetX > width * 0.7) {
          this.nextPage()
        } else {
          this.toggleTitleAndMenu()
        }
      },
      // 解析电子书内容
      parseBook () {
        // 获取电子书封面
        this.book.loaded.cover.then(cover => {
          this.book.archive.createUrl(cover).then(url => {
            this.setCover(url)
          })
        })
        // 获取书籍的基本信息
        this.book.loaded.metadata.then(metadata => {
          this.setMetadata(metadata)
        })
        // 获取书籍的目录
        this.book.loaded.navigation.then(nav => {
          const navItem = flatten(nav.toc)

          function find (item, level = 0) {
            return !item.parent ? level : find(navItem.filter(parentItem => parentItem.id === item.parent)[0], ++level)
          }

          navItem.forEach(item => {
            item.level = find(item)
          })
          this.setNavigation(navItem)
        })
      },
      // 渲染的初始化过程
      initRendition () {
        // 通过Book.renderTo生成Rendition对象
        this.rendition = this.book.renderTo('read', {
          width: innerWidth,
          height: innerHeight,
          method: 'default' // 解决微信端无法显示问题
          // flow: 'scrolled'// 滚动模式阅读  本项目使用的是默认的翻页模式
        })
        const location = getLocation(this.fileName)
        // console.log(location)
        // 通过Rendtion.display渲染电子书
        this.display(location, () => {
          this.initTheme()
          this.initFontSize()
          this.initFontFamily()
          this.initGlobalStyle()
        })
        // 加载字体
        // contents 表示管理资源
        this.rendition.hooks.content.register(contents => {
          Promise.all([
            contents.addStylesheet(`${process.env.VUE_APP_RES_URL}/fonts/daysOne.css`),
            contents.addStylesheet(`${process.env.VUE_APP_RES_URL}/fonts/cabin.css`),
            contents.addStylesheet(`${process.env.VUE_APP_RES_URL}/fonts/montserrat.css`),
            contents.addStylesheet(`${process.env.VUE_APP_RES_URL}/fonts/tangerine.css`)
          ]).then(() => {
          })
        })
      },
      // 设置初次话默认主题
      initTheme () {
        let defaultTheme = getTheme(this.fileName)
        if (!defaultTheme) {
          defaultTheme = this.themeList[0].name
          saveTheme(this.fileName, defaultTheme)
        }
        this.setDefaultTheme(defaultTheme)
        this.themeList.forEach(theme => {
          // 注册主题
          this.rendition.themes.register(theme.name, theme.style)
        })
        // 设置主题
        this.rendition.themes.select(defaultTheme)
      },
      // 设置初次话默认字号
      initFontSize () {
        let fontSize = getFontSize(this.fileName)
        if (!fontSize) {
          saveFontSize(this.fileName, this.defaultFontSize)
        } else {
          this.rendition.themes.fontSize(fontSize)
          this.setDefaultFontSize(fontSize)
        }
      },
      // 设置初次话默认字体
      initFontFamily () {
        let font = getFontFamily(this.fileName)
        // 获取存储LocalStorage
        if (!font) {
          saveFontFamily(this.fileName, this.defaultFontFamily)
        } else {
          // 初始化设置字体样式
          this.rendition.themes.font(font)
          this.setDefaultFontFamily(font)
        }
      },
      // 初始化手势
      initGesture () {
        this.rendition.on('touchstart', event => {
          // console.log(event)
          // 记录手势启始位置x
          this.touchStartX = event.changedTouches[0].clientX
          // 记录手势开始的时间
          this.touchStartTime = event.timeStamp
        })
        this.rendition.on('touchend', event => {
          // console.log(event)
          // 计算手势结束的位置
          const offsetX = event.changedTouches[0].clientX - this.touchStartX
          // 计算手势所用的时间
          const time = event.timeStamp - this.touchStartTime
          // 判断是否企启用手势
          if (time < 500 && offsetX > 40) {
            this.prevPage()
          } else if (time < 500 && offsetX < -40) {
            this.nextPage()
          } else {
            this.toggleTitleAndMenu()
          }
          // 禁用事件默认事件
          event.preventDefault()
          // 禁止事件传播
          event.stopPropagation()
        })
      },
      // 上一页
      prevPage () {
        if (this.rendition) {
          this.rendition.prev().then(() => {
            this.refreshLocation()
          })
          this.hideTitleAndMenu()
        }
      },
      // 下一页
      nextPage () {
        if (this.rendition) {
          this.rendition.next().then(() => {
            this.refreshLocation()
          })
          this.hideTitleAndMenu()
        }
      },
      // 功能菜单显示隐藏
      toggleTitleAndMenu () {
        if (this.menuVisible) {
          this.setSettingVisible(-1)
          this.setFontFamilyVisible(false)
        }
        this.setMenuVisible(!this.menuVisible)
      },
      initEpub () {
        // 生成Book对象
        const url = process.env.VUE_APP_RES_URL + '/epub/' + this.fileName + '.epub'
        // console.log(url)
        this.book = new Epub(url)
        this.setCurrentBook(this.book)
        this.initRendition()
        // this.initGesture()
        this.parseBook()
        // 初次载入分页
        this.book.ready.then(() => {
          return this.book.locations.generate(750 * (window.innerWidth / 375) * (getFontSize(this.fileName) / 16))
        }).then(locations => {
          // console.log(locations)
          this.navigation.forEach(nav => {
            nav.pagelist = []
          })
          locations.forEach(item => {
            const loc = item.match(/\[(.*)\]!/)[1]
            this.navigation.forEach(nav => {
              if (nav.href) {
                const href = nav.href.match(/^(.*)\.html$/)[1]
                if (href === loc) {
                  nav.pagelist.push(item)
                }
              }
            })
            let currentPage = 1
            this.navigation.forEach((nav, index) => {
              if (index === 0) {
                nav.page = 1
              } else {
                nav.page = currentPage
              }
              currentPage += nav.pagelist.length
            })
            // console.log(this.navigation)
          })
          // console.log(locations)
          this.setPagelist(locations)
          this.setBookAvailable(true)
          this.refreshLocation()
        })
      }
    },
    mounted () {
      this.setFileName(this.$route.params.fileName.split('|').join('/')).then(() => {
        this.initEpub()
      })
    }
  }
</script>

<style lang="scss" rel="stylesheet/scss" scoped>
    @import "../../assets/styles/global";

    .ebook-reader {
        width: 100%;
        height: 100%;
        overflow: hidden;

        .ebook-reader-mask {
            position: absolute;
            top: 0;
            left: 0;
            background: transparent; // 透明
            z-index: 150;
            width: 100%;
            height: 100%;
        }
    }
</style>
